import trac,{pauseTracking,resumeTracking } from "../../effect/track.js";
import { TrackOpTypes,isObject,RAW } from "../../util.js";
import { reactive } from "../../reactive.js";

// 用来存放被重写的数组方法
const arrayInstrumentations = {};

// 重写数组这几个方法
["includes","indexOf","lastIndexOf"].forEach((key) => {
  arrayInstrumentations[key] = function(...args) {
    // 先代理对象中查找，如果找不到再去原始对象中查找
    const res = Array.prototype[key].apply(this, args);
    if(res < 0 || res === false) {
      return Array.prototype[key].apply(this[RAW], args);
    }
    return res;
  }
});


["push","pop","unshift","shift","splice"].forEach((key) => {
  arrayInstrumentations[key] = function(...args) {
    pauseTracking();
    const res = Array.prototype[key].apply(this,args);
    resumeTracking();
    return res;
  }
})

/**
 * 
 * @param {*} target 原始对象
 * @param {*} key 对象的属性
 * @returns 
 */
// 导出一个默认函数，该函数接收两个参数：target 和 key
export default function (target, key) {
  // 如果访问了特殊标识raw则直接返回原始对象
  if(key === RAW) {
    return target;
  }

  // 调用 track 函数，记录当前读取操作，参数包括目标对象、操作类型和键名
  track(target, TrackOpTypes.GET, key);
  // 如果当前读取的是数组的某些方法，则返回重写后的方法
  if(Array.isArray(target) && arrayInstrumentations.hasOwnProperty(key)) {
    return arrayInstrumentations[key];
  }

  const result = Reflect.get(target, key);
  if (isObject(result)) {
    return reactive(result);
  }

  return result;
}
